/** 
 * 年度点评控制器模块
 */
module controller.AnnualReviewController;

import std.conv : to;

import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
import vibe.data.json : Json, serializeToJsonString;

import model.AnnualReview;
import repository.AnnualReviewRepo;

import utils.ObjMapping : ObjMapping;
import utils.RespData : RespData;
import utils.DataCache;
import utils.CacheKey : CacheKey;
import utils.SecurityVerification : signValidator;

AnnualReviewRepo _arRepo;

static this ()
{
    _arRepo = new AnnualReviewRepo();
}

static ~this ()
{
    destroy(_arRepo);
}

/** 
* 获取全部年度点评列表数据
*/
void getAllAnnualReviewList (HTTPServerRequest req, HTTPServerResponse resp)
{
    // 缓存中有数据直接取出返回
    auto data = cacheData.get(CacheKey.ANNUALREVIEW_ALLLIST_CACHE);
    if (!data.isNull)
    {
        resp.writeJsonBody(RespData.newData(200, "ok", data.get));
        return;
    }

    AnnualReview[] annualReviewList = _arRepo.getAllAnnualReviewList();
    // 转换为Dto对象
    AnnualReviewDto[] annualReviewDtoList = [];
    foreach (an; annualReviewList)
    {
        annualReviewDtoList ~= ObjMapping.mappingToObject!(AnnualReviewDto, AnnualReview)(
            an);
    }

    // 设置缓存
    string jsonList = serializeToJsonString(annualReviewDtoList);
    cacheData.put(CacheKey.ANNUALREVIEW_ALLLIST_CACHE, jsonList);

    resp.writeJsonBody(RespData.newData(200, "ok", jsonList));
}

/** 
* 获取年度点评列表数据
*   - 视频类型（1：电视剧，2：电影，3：年度点评）
*/
void getAnnualReviewList (HTTPServerRequest req, HTTPServerResponse resp)
{
    import std.format : format;

    string videoCateStr = req.query.get("vcate", "");
    if (videoCateStr == "")
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"));
        return;
    }
    uint videoCate = to!uint(videoCateStr);

    // 后台管理请求不走缓存
    if ("X-Admin-Req" !in req.headers)
    {
        // 缓存中有数据直接取出返回
        auto data = cacheData.get(CacheKey.ANNUALREVIEW_LIST_CACHE ~ videoCateStr);
        if (!data.isNull)
        {
            resp.writeJsonBody(RespData.newData(200, "ok", data.get));
            return;
        }
    }

    AnnualReview[] annualReviewList = _arRepo.getAnnualReviewList(videoCate);
    // 转换为Dto对象
    AnnualReviewDto[] annualReviewDtoList = [];
    foreach (an; annualReviewList)
    {
        annualReviewDtoList ~= ObjMapping.mappingToObject!(AnnualReviewDto, AnnualReview)(
            an);
    }

    // 设置缓存
    string jsonList = serializeToJsonString(annualReviewDtoList);
    cacheData.put(CacheKey.ANNUALREVIEW_LIST_CACHE ~ videoCateStr, jsonList);

    resp.writeJsonBody(RespData.newData(200, "ok", jsonList));
}

// 后台接口函数，需进行token校验--------------------------------------------

/** 
* 添加年度点评
*/
void addAnnualReview (HTTPServerRequest req, HTTPServerResponse resp)
{
    Json json = req.json;
    uint year = json["year"].to!uint();
    uint vcate = json["vCate"].to!uint();
    string comment = json["comment"].to!string();

    string sign = json["sign"].to!string();

    import std.format : format;

    string reqParamsStr = format("%s%s%s", year, vcate, comment);
    if (!signValidator(reqParamsStr, sign))
    {
        resp.writeJsonBody(RespData.newData(403, "签名不正确！"), 403);
        return;
    }

    auto ar = new AnnualReviewDtoFromCreate(year, comment, vcate);
    bool res = _arRepo.addAnnualReview(
        ObjMapping.mappingToObject!(AnnualReview, AnnualReviewDtoFromCreate)(
            ar));
    if (!res)
    {
        resp.writeJsonBody(RespData.newData(500, "error"), 500);
        return;
    }
    resp.writeJsonBody(RespData.newData(200, "ok"), 201);
}

/** 
* 编辑年度点评
*/
void editAnnualReview (HTTPServerRequest req, HTTPServerResponse resp)
{
    string idStr = req.params.get("id", "");
    if (idStr == "")
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"));
        return;
    }
    uint id = to!uint(idStr);

    Json json = req.json;
    uint year = json["year"].to!uint();
    string comment = json["comment"].to!string();

    string sign = json["sign"].to!string();

    import std.format : format;

    string reqParamsStr = format("%s%s", year, comment);
    if (!signValidator(reqParamsStr, sign))
    {
        resp.writeJsonBody(RespData.newData(403, "签名不正确！"), 403);
        return;
    }

    auto ar = new AnnualReviewDtoFromUpdate(year, comment);
    bool res = _arRepo.updateAnnualReview(id, ObjMapping.mappingToObject!(AnnualReview, AnnualReviewDtoFromUpdate)(
            ar));
    if (!res)
    {
        resp.writeJsonBody(RespData.newData(500, "error"), 500);
        return;
    }
    resp.writeJsonBody(RespData.newData(200, "ok"));
}

/** 
* 删除年度点评
*/
void deleteAnnualReview (HTTPServerRequest req, HTTPServerResponse resp)
{
    string idStr = req.params.get("id", "");
    string sign = req.query.get("sign", "");
    if (idStr == "" || sign == "")
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"));
        return;
    }
    uint id = to!uint(idStr);

    if (!signValidator(idStr, sign))
    {
        resp.writeJsonBody(RespData.newData(403, "签名不正确！"), 403);
        return;
    }

    bool res = _arRepo.removeAnnualReview(id);
    if (!res)
    {
        resp.writeJsonBody(RespData.newData(500, "error"), 500);
        return;
    }
    resp.writeJsonBody(RespData.newData(200, "ok"));
}
